home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP11.ZIP / CHAP11 / HSCHMOO / FIGURE.CPP next >
C/C++ Source or Header  |  1993-06-22  |  9KB  |  365 lines

  1. /*
  2.  * FIGURE.CPP
  3.  * Schmoo Figure Handler Chapter 11
  4.  *
  5.  * Implementation of the CFigure class that we expose as a SchmooFigure
  6.  * Object in this handler.
  7.  *
  8.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Software Design Engineer
  11.  * Microsoft Systems Developer Relations
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include "hschmoo.h"
  19.  
  20.  
  21. /*
  22.  * CFigure:CFigure
  23.  * CFigure::~CFigure
  24.  *
  25.  * Constructor Parameters:
  26.  *  punkOuter       LPUNKNOWN of the controlling unknown.
  27.  *  pfnDestroy      LPFNDESTROYED to call when an object is destroyed.
  28.  *  hInst           HINSTANCE of the application we're in.
  29.  */
  30.  
  31. CFigure::CFigure(LPUNKNOWN punkOuter, LPFNDESTROYED pfnDestroy
  32.     , HINSTANCE hInst)
  33.     {
  34.     m_cRef=0;
  35.     m_punkOuter=punkOuter;
  36.     m_pfnDestroy=pfnDestroy;
  37.     m_clsID=CLSID_Schmoo2Figure;
  38.  
  39.     m_cf=RegisterClipboardFormat(SZPOLYLINECLIPFORMAT);
  40.  
  41.     //NULL any contained interfaces initially.
  42.     m_pIOleObject        =NULL;
  43.     m_pIViewObject       =NULL;
  44.     m_pIPersistStorage   =NULL;
  45.     m_pIAdviseSink       =NULL;
  46.  
  47.     m_pDefIUnknown       =NULL;
  48.     m_pDefIOleObject     =NULL;
  49.     m_pDefIViewObject    =NULL;
  50.     m_pDefIPersistStorage=NULL;
  51.     m_pDefIDataObject    =NULL;
  52.  
  53.     m_pIAdvSinkView      =NULL;
  54.     m_dwAdviseFlags      =0;
  55.     m_dwAdviseAspects    =0;
  56.     m_dwFrozenAspects    =0;
  57.  
  58.     return;
  59.     }
  60.  
  61.  
  62. CFigure::~CFigure(void)
  63.     {
  64.     if (NULL!=m_pIAdvSinkView)
  65.         m_pIAdvSinkView->Release();
  66.  
  67.     if (NULL!=m_pDefIDataObject)
  68.         m_pDefIDataObject->Release();
  69.  
  70.     if (NULL!=m_pDefIPersistStorage)
  71.         m_pDefIPersistStorage->Release();
  72.  
  73.     if (NULL!=m_pDefIViewObject)
  74.         m_pDefIViewObject->Release();
  75.  
  76.     if (NULL!=m_pDefIOleObject)
  77.         m_pDefIOleObject->Release();
  78.  
  79.     if (NULL!=m_pDefIUnknown)
  80.         m_pDefIUnknown->Release();
  81.  
  82.     if (NULL!=m_pIAdviseSink)
  83.         delete m_pIAdviseSink;
  84.  
  85.     if (NULL!=m_pIPersistStorage)
  86.         delete m_pIPersistStorage;
  87.  
  88.     if (NULL!=m_pIViewObject)
  89.         delete m_pIViewObject;
  90.  
  91.     if (NULL!=m_pIOleObject)
  92.         delete m_pIOleObject;
  93.  
  94.     return;
  95.     }
  96.  
  97.  
  98.  
  99.  
  100. /*
  101.  * CFigure::FInit
  102.  *
  103.  * Purpose:
  104.  *  Performs any intiailization of a CFigure that's prone to failure
  105.  *  that we also use internally before exposing the object outside
  106.  *  this DLL.
  107.  *
  108.  * Parameters:
  109.  *  None
  110.  *
  111.  * Return Value:
  112.  *  BOOL            TRUE if the function is successful, FALSE otherwise.
  113.  */
  114.  
  115. BOOL CFigure::FInit(void)
  116.     {
  117.     LPUNKNOWN       pIUnknown=(LPUNKNOWN)this;
  118.     HRESULT         hr;
  119.     DWORD           dwConn;
  120.     FORMATETC       fe;
  121.  
  122.     if (NULL!=m_punkOuter)
  123.         pIUnknown=m_punkOuter;
  124.  
  125.     //First create our interfaces.
  126.     m_pIOleObject=new CImpIOleObject(this, pIUnknown);
  127.  
  128.     if (NULL==m_pIOleObject)
  129.         return FALSE;
  130.  
  131.     m_pIViewObject=new CImpIViewObject(this, pIUnknown);
  132.  
  133.     if (NULL==m_pIViewObject)
  134.         return FALSE;
  135.  
  136.     m_pIPersistStorage=new CImpIPersistStorage(this, pIUnknown);
  137.  
  138.     if (NULL==m_pIPersistStorage)
  139.         return FALSE;
  140.  
  141.     m_pIAdviseSink=new CImpIAdviseSink(this, pIUnknown);
  142.  
  143.     if (NULL==m_pIAdviseSink)
  144.         return FALSE;
  145.  
  146.     /*
  147.      * Get an IUnknown on the default handler, passing pIUnknown
  148.      * as the controlling unknown.
  149.      */
  150.     hr=OleCreateDefaultHandler(CLSID_Schmoo2Figure, pIUnknown, IID_IUnknown
  151.         , (LPLPVOID)&m_pDefIUnknown);
  152.  
  153.     if (FAILED(hr))
  154.         return FALSE;
  155.  
  156.     //Now try to get other interfaces to which we delegate
  157.     hr=m_pDefIUnknown->QueryInterface(IID_IOleObject
  158.         , (LPLPVOID)&m_pDefIOleObject);
  159.  
  160.     if (FAILED(hr))
  161.         return FALSE;
  162.  
  163.     hr=m_pDefIUnknown->QueryInterface(IID_IViewObject
  164.         , (LPLPVOID)&m_pDefIViewObject);
  165.  
  166.     if (FAILED(hr))
  167.         return FALSE;
  168.  
  169.     hr=m_pDefIUnknown->QueryInterface(IID_IDataObject
  170.         , (LPLPVOID)&m_pDefIDataObject);
  171.  
  172.     if (FAILED(hr))
  173.         return FALSE;
  174.  
  175.     hr=m_pDefIUnknown->QueryInterface(IID_IPersistStorage
  176.         , (LPLPVOID)&m_pDefIPersistStorage);
  177.  
  178.     if (FAILED(hr))
  179.         return FALSE;
  180.  
  181.     //Set up an advise on native data so we can keep in sync
  182.     SETDefFormatEtc(fe, m_cf, TYMED_HGLOBAL);
  183.     m_pDefIDataObject->DAdvise(&fe, 0, m_pIAdviseSink, &dwConn);
  184.  
  185.     return TRUE;
  186.     }
  187.  
  188.  
  189.  
  190.  
  191.  
  192. /*
  193.  * CFigure::QueryInterface
  194.  * CFigure::AddRef
  195.  * CFigure::Release
  196.  *
  197.  * Purpose:
  198.  *  IUnknown members for CFigure object.
  199.  */
  200.  
  201. STDMETHODIMP CFigure::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  202.     {
  203.     *ppv=NULL;
  204.  
  205.     /*
  206.      * The only calls we get here for IUnknown are either in a non-aggregated
  207.      * case or when we're created in an aggregation, so in either we always
  208.      * return our IUnknown for IID_IUnknown.
  209.      */
  210.     if (IsEqualIID(riid, IID_IUnknown))
  211.         *ppv=(LPVOID)this;
  212.  
  213.     if (IsEqualIID(riid, IID_IPersist) || IsEqualIID(riid, IID_IPersistStorage))
  214.         *ppv=(LPVOID)m_pIPersistStorage;
  215.  
  216.     if (IsEqualIID(riid, IID_IOleObject))
  217.         *ppv=(LPVOID)m_pIOleObject;
  218.  
  219.     if (IsEqualIID(riid, IID_IViewObject))
  220.         *ppv=(LPVOID)m_pIViewObject;
  221.  
  222.     //AddRef any interface we'll return.
  223.     if (NULL!=*ppv)
  224.         {
  225.         ((LPUNKNOWN)*ppv)->AddRef();
  226.         return NOERROR;
  227.         }
  228.  
  229.     //Otherwise see if the default handler knows it.
  230.     return m_pDefIUnknown->QueryInterface(riid, ppv);
  231.     }
  232.  
  233.  
  234. STDMETHODIMP_(ULONG) CFigure::AddRef(void)
  235.     {
  236.     return ++m_cRef;
  237.     }
  238.  
  239.  
  240. STDMETHODIMP_(ULONG) CFigure::Release(void)
  241.     {
  242.     ULONG       cRefT;
  243.  
  244.     cRefT=--m_cRef;
  245.  
  246.     if (0==m_cRef)
  247.         delete this;
  248.  
  249.     return cRefT;
  250.     }
  251.  
  252.  
  253.  
  254.  
  255.  
  256. /*
  257.  * CFigure::Draw
  258.  *
  259.  * Purpose:
  260.  *  Paints the current window to an hDC which might be a printer.
  261.  *
  262.  * Parameters:
  263.  *  hDC             HDC to draw on, could be a metafile or printer DC.
  264.  *  pRect           LPRECT defining the bounds on hDC in which to draw.
  265.  *  dwAspect        DWORD aspect to draw.
  266.  *  ptd             DVTARGETDEVICE FAR * containing device information.
  267.  *  hICDev          HDC containing the IC for the device.
  268.  *  ppl             LPPOLYLINEDATA from which to draw.
  269.  *
  270.  * Return Value:
  271.  *  None
  272.  */
  273.  
  274. void CFigure::Draw(HDC hDC, LPRECT pRect, DWORD dwAspect
  275.     , DVTARGETDEVICE FAR * ptd, HDC hICDev, LPPOLYLINEDATA ppl)
  276.     {
  277.     HBRUSH          hBrush;
  278.     HPEN            hPen;
  279.     HGDIOBJ         hObj1, hObj2;
  280.     UINT            i, j;
  281.     POINT           pt[2];
  282.     int             nDC;
  283.  
  284.     nDC=SaveDC(hDC);
  285.  
  286.     hPen=CreatePen(ppl->iLineStyle, 1, ppl->rgbLine);
  287.     hObj1=SelectObject(hDC, hPen);
  288.  
  289.     hBrush=CreateSolidBrush(ppl->rgbBackground);
  290.     hObj2=SelectObject(hDC, hBrush);
  291.     SetBkColor(hDC, ppl->rgbBackground);
  292.  
  293.     //If we only had one point, draw a dot to indicate it's position.
  294.     if (1==ppl->cPoints)
  295.         {
  296.         pt[0]=ppl->rgpt[0];
  297.         PointScale(pRect, &pt[0], TRUE);
  298.         SetPixel(hDC, pt[0].x, pt[0].y, ppl->rgbLine);
  299.         }
  300.     else
  301.         {
  302.         //Erase the background for bitmaps and metafiles.
  303.         SelectObject(hDC, GetStockObject(NULL_PEN));
  304.         Rectangle(hDC, pRect->left, pRect->top, pRect->right+1, pRect->bottom+1);
  305.         SelectObject(hDC, hPen);
  306.  
  307.         for (i=0; i < ppl->cPoints; i++)
  308.             {
  309.             for (j=i; j < ppl->cPoints; j++)
  310.                 {
  311.                 pt[0]=ppl->rgpt[i];
  312.                 pt[1]=ppl->rgpt[j];
  313.                 PointScale(pRect, &pt[0], TRUE);
  314.                 PointScale(pRect, &pt[1], TRUE);
  315.                 MoveTo(hDC, pt[0].x, pt[0].y);
  316.                 LineTo(hDC, pt[1].x, pt[1].y);
  317.                 }
  318.             }
  319.         }
  320.  
  321.     SelectObject(hDC, hObj1);
  322.     SelectObject(hDC, hObj2);
  323.     DeleteObject(hBrush);
  324.     DeleteObject(hPen);
  325.  
  326.     RestoreDC(hDC, nDC);
  327.     return;
  328.     }
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336. /*
  337.  * CFIgure::PointScale
  338.  *
  339.  * Purpose:
  340.  *  Scales a point from a 0-32767 coordinate to a rectangle relative
  341.  *  coordinate.
  342.  *
  343.  * Parameters:
  344.  *  pRect           LPRECT in which to scale.
  345.  *  ppt             LPPOINT to convert
  346.  *  fUnused         BOOL of no use.
  347.  *
  348.  * Return Value:
  349.  *  None
  350.  */
  351.  
  352. void CFigure::PointScale(LPRECT pRect, LPPOINT ppt, BOOL fUnused)
  353.     {
  354.     DWORD   cx, cy;
  355.  
  356.     cx=(DWORD)(pRect->right-pRect->left);
  357.     cy=(DWORD)(pRect->bottom-pRect->top);
  358.  
  359.     //Must use DWORD to insure proper scaling.
  360.     ppt->x=pRect->left+(UINT)(((DWORD)ppt->x*cx) >> 15);
  361.     ppt->y=pRect->top+(UINT)(((DWORD)ppt->y*cy) >> 15);
  362.  
  363.     return;
  364.     }
  365.